<?php
/**
 * Created by PhpStorm.
 * User: s.utkin
 * Date: 16.12.2014
 * Time: 17:56
 */

namespace FlashMessages;

use Pinenut\Model2\Embedded\ReferenceContainer\One;
use Pinenut\Model2\Embedded\Reference;
use Pinenut\Model2\Finder;
use Pinenut\User\Profile;

/**
 * Модель flash-сообщения
 *
 * @package FlashMessages
 */
class FlashMessage extends \Model {

	/**
	 * Хэш сообщения
	 *
	 * @var string
	 */
	public $hash;

	/**
	 * Стиль уведомления (Например: default, messengerItem, ...)
	 * Служит дополнительным параметром для принятия решения об обработке уведомления.
	 * Пример:
	 * 	По приходу неблокирующего необязательного уведомления со стилем 'messengerItem'
	 *	мы можем решить, что не стоит показывать это уведомление, если отркыто окно мессенджера
	 *
	 * @var string
	 */
	public $style;

	/**
	 * Профиль пользователя, которому адресовано flash-сообщение
	 *
	 * @var One
	 */
	public $profile;

	/**
	 * Имя и параметры экшена, который отрисовывает flash-сообщение
	 * [
	 *   'name' => 'action.path',
	 *   'params' => [
	 *       'param1' => $value1,
	 *       'param2' => $value2,
	 *       ...
	 *       'param_N' => $value_N,
	 *   ],
	 * ]
	 * @var array
	 */
	public $action;

	/**
	 * Признак того, что flash-сообщение блокирующее
	 *
	 * @var boolean
	 */
	public $isBlocking;

	/**
	 * Признак того, что flash-сообщение обязательное
	 *
	 * @var boolean
	 */
	public $isRequired;

	/**
	 * Признак того, что flash-сообщение обработано
	 *
	 * @var boolean
	 */
	public $isProcessed;

	public static function fields()
	{
		return array_merge(
			parent::fields(),
			[
				'profile' => [
					One::className(),
					Reference::className(),
					Profile::className()
				],
				'action' => static::MIXED,
				'isBlocking' => static::BOOLEAN,
				'isRequired' => static::BOOLEAN,
				'isProcessed' => static::BOOLEAN,
				'style' => static::STRING,
				'hash' => static::STRING,
			]
		);
	}

	/**
	 * @param $targetProfileId - id профиля пользователя, которому отправляется сообщение
	 * @param $actionName - имя экшена, который возвращает содержимое flash-сообщения
	 * @param array $actionParams - параметры экшена, который возвращает содержимое flash-сообщения
	 * @param bool $isRequired - признае того, что flash-сообщение обязательное
	 * @param bool $isBlocking - признае того, что flash-сообщение блокирующее
	 * @param bool $isProcessed - признае того, что flash-сообщение обработано
	 * @param string $style - стиль сообщения
	 *
	 * @return static
	 */
	public static function addMessage($targetProfileId, $actionName, $actionParams = [], $isRequired = false, $isBlocking = false, $isProcessed = false, $style = 'default')
	{
		$flashMessageModel = new static;
		$flashMessageModel->profile[$targetProfileId];
		$flashMessageModel->action = [
			'name' => $actionName,
			'params' => $actionParams,
		];
		$flashMessageModel->isBlocking = $isBlocking;
		$flashMessageModel->isRequired = $isRequired;
		$flashMessageModel->isProcessed = $isProcessed;
		$flashMessageModel->style = $style;
		$flashMessageModel->hash = static::getMessageHash($flashMessageModel);
		$flashMessageModel->save();

		return $flashMessageModel;
	}

	/**
	 * @param $targetProfileId - id профиля пользователя, которому отправляется сообщение
	 * @param $actionName - имя экшена, который возвращает содержимое flash-сообщения
	 * @param array $actionParams - параметры экшена, который возвращает содержимое flash-сообщения
	 * @param bool $isRequired - признае того, что flash-сообщение обязательное
	 * @param bool $isBlocking - признае того, что flash-сообщение блокирующее
	 * @param bool $isProcessed - признае того, что flash-сообщение обработано
	 * @param string $style - стиль сообщения
	 */
	public static function sendMessage($targetProfileId, $actionName, $actionParams = [], $isRequired = false, $isBlocking = false, $isProcessed = false, $style = 'default')
	{
		$message = static::addMessage($targetProfileId, $actionName, $actionParams, $isRequired, $isBlocking, $isProcessed, $style);

		Queue::enqueue(
			[
				'type' => \FlashMessagesNotificationDeliveryConfig::FLASH_MESSAGE_SEND,
				'data' => [
					'flashMessageId' => (string)$message,
					'targetProfileId' => (string)$message->profile,
				],
			]
		);
	}

	/**
	 * @param $profileId
	 * @param $idList
	 * @return static[]
	 */
	public static function getProfilesMessagesByIdList($profileId, $idList)
	{
		$finder = static::find();
		$finder->where('profile._ref', $profileId);
		$finder->where('_id', $idList, Finder::OP_IN);

		return $finder->all();
	}

	/**
	 * @param $profileId
	 * @param $hashList
	 * @return static[]
	 */
	public static function getProfilesMessagesByHashList($profileId, $hashList)
	{
		$finder = static::find();
		$finder->where('profile._ref', $profileId);
		$finder->where('hash', $hashList, Finder::OP_IN);

		return $finder->all();
	}

	/**
	 * Get all Profile required notices
	 *
	 * @param string $profileId - User Identity
	 *
	 * @return array $collection
	 */
	public static function getProfileRequiredNotices($profileId)
	{
		$model = FlashMessage::find();
		$model->where('profile._ref', $profileId);
		$model->where('isRequired', true);
		$model->where('isProcessed', false);
		$collectionIds = $model->all();

		return $collectionIds;
	}

	/**
	 * @param static $message
	 * @return string
	 */
	protected static function getMessageHash($message) {
		return md5((string)$message->profile .
			$message->style .
			serialize($message->action) .
			($message->isBlocking ? 1 : 0) .
			($message->isRequired ? 1 : 0));
	}
}